package org.zfes.snowier.zbss.xzy.biz.solution.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZObjectUtil;
import org.zfes.snowier.core.util.ZStrUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.core.data.ParamMap;
import com.google.common.collect.Lists;
import org.zfes.snowier.core.data.SelectVo;
import org.zfes.snowier.zbss.xzy.biz.device.model.Device;
import org.zfes.snowier.zbss.xzy.biz.device.service.IDeviceService;
import org.zfes.snowier.zbss.xzy.biz.solution.dao.SolutionDeviceMapper;
import org.zfes.snowier.zbss.xzy.biz.solution.model.Solution;
import org.zfes.snowier.zbss.xzy.biz.solution.model.SolutionDevice;
import org.zfes.snowier.zbss.xzy.biz.solution.service.ISolutionAlgorithmService;
import org.zfes.snowier.zbss.xzy.biz.solution.service.ISolutionDeviceService;
import org.zfes.snowier.zbss.xzy.biz.solution.service.ISolutionService;
import org.zfes.snowier.zbss.xzy.device.DeviceDto;
import org.zfes.snowier.zbss.xzy.solution.SolutionDto;

import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class SolutionDeviceServiceImpl implements ISolutionDeviceService{
 	@Autowired
	private SolutionDeviceMapper solutionDeviceMapper;
 	@Autowired
	private IDeviceService deviceService;
 	@Autowired
	private ISolutionService solutionService;
 
 	@Autowired ISolutionAlgorithmService solutionAlgorithmService;
 	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override                
	public List<SolutionDto> loadSolutionsDeviceConfiged(Long deviceId){
 		if(deviceId==null) {
 			return Lists.newArrayList();
 		}
 		
 		List<Long> solutionIds=loadByDeviceId(deviceId).stream().map(v->v.getSolutionId()).collect(Collectors.toList());
 		
 		Map<Long,Integer> solAlgCount= solutionAlgorithmService.loadSolAlgCount();
 		
 		
 		List<SolutionDto>  soltionListConfiged = solutionService.loadByIds(solutionIds)
	 				.stream().map(v->{
			 			SolutionDto sdto = new SolutionDto();
			 			ZBeanUtil.copy(v,sdto);
			 			sdto.setAlgCount(solAlgCount.get(v.getId()));
			 			return sdto;
		}).collect(Collectors.toList());
 		return soltionListConfiged;
    }
 	
 	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<SolutionDto> loadSolutionsDeviceNotConfiged(Long deviceId,String name){
 		if(deviceId==null) {
 			return Lists.newArrayList();
 		}
 		List<Long> solutionIds=loadByDeviceId(deviceId).stream().map(v->v.getSolutionId()).collect(Collectors.toList());
 		
 		Map<Long,Integer> solAlgCount = solutionAlgorithmService.loadSolAlgCount();
 		
 		List<SolutionDto>  soltionListNotConfiged = solutionService.loadByIdsNotIn(solutionIds,name)
 				.stream().map(v->{
			 			SolutionDto sdto =new SolutionDto();
			 			ZBeanUtil.copy(v, sdto);
			 			sdto.setAlgCount(solAlgCount.get(v.getId()));
			 			return sdto;
			}).collect(Collectors.toList());
 		
 		return soltionListNotConfiged;
    }
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<SolutionDevice> loadByDeviceId(Long deivceId){
 		if(deivceId == null) {
 			return Lists.newArrayList();
 		}
 		return solutionDeviceMapper.selectByDeviceId(deivceId);
 	}
	
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createSolutionDevice(SolutionDevice solutionDevice) {
		ZBeanUtil.setCreateInfo(solutionDevice);
		ZBeanUtil.validateBean(solutionDevice);
		solutionDeviceMapper.insertSelective(solutionDevice);
	}
	
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void bindDeviceSolutions(Long deviceId, List<Long> solutionIds) {
		ZAssert.notNull(deviceId, "请选择设备");
		ZAssert.notEmpty(solutionIds,  "请选择解决方案");
		unbindDeviceSolutions(deviceId, solutionIds);
		
		solutionIds.forEach(sid->{
			createSolutionDevice(new SolutionDevice(  deviceId, sid));
		});
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<SolutionDevice> loadSolutionDeviceById(Long id) {
		if(id!=null){
			return Optional.ofNullable(solutionDeviceMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
		
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<SolutionDevice> loadBydevIdAndSolId(Long deviceId,Long solutionId){
		if(ZObjectUtil.isEmpty(deviceId)||ZObjectUtil.isEmpty(solutionId)) {
			return Optional.empty();
		}
		return Optional.ofNullable(solutionDeviceMapper.selectBydevIdAndSolId(deviceId,solutionId));
	}
	
	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void unbindDeviceSolutions(Long deviceId,List<Long> solutionIds) {
		ZAssert.notNull(deviceId, "请选择设备");
		ZAssert.notEmpty(solutionIds,  "请选择解决方案");
		solutionDeviceMapper.deleteBydevIdAndSolIds(deviceId,solutionIds);
		
	}
	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public  void deleteBydeviceId(Long deviceId) {
		ZAssert.notNull(deviceId, "请选择设备");
		solutionDeviceMapper.deleteBydeviceId(deviceId);
	 }

	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadSolutionDeviceDataSet(Map<String, Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		DataSet ds=DataSet.newDS2(solutionDeviceMapper.selectListCount(pm), solutionDeviceMapper.selectMapListPage(pm));
		return ds;
	}
	
//	@Transactional(rollbackFor=Exception.class,readOnly=true)
//	@Override
//	public Optional<SolutionDeviceDto> loadSolutionforDeviceConfig(Long deviceId) {
//		
//		Device device= deviceService.loadDeviceById(deviceId).orElseThrow(()->ZAlert.newSLE("未查询到数据"));
//		
//		List<SolutionDevice>  solutionDeviceList = loadByDeviceId( deviceId);
//		
//		List<Solution>  soltionListNotCOnfiged = solutionService.loadByIdsNotIn(solutionDeviceList.stream().map(v->v.getDeviceId()).collect(Collectors.toList()));
//		
//		
//		SolutionDeviceDto solutionDeviceDto=new SolutionDeviceDto();
//		
//		return Optional.ofNullable(solutionDeviceDto);
//	}
}